home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / rpg / crossfir.92 / crossfir / crossfire-0.92.5 / lib / xbmtobdf.c < prev    next >
C/C++ Source or Header  |  1996-07-24  |  9KB  |  339 lines

  1. /*
  2.  * static char *rcsid_xbmtobdf_c =
  3.  *   "$Id: xbmtobdf.c,v 1.1 1996/07/24 07:25:58 master Exp master $";
  4.  */
  5.  
  6. /*
  7.  * xbmtobdf - converts many xbm bitmaps into one bdf font file.
  8.  * Kjetil T. Homme 1992
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <time.h>
  13. #include <ctype.h>
  14. #include <string.h>
  15. #if !defined(vax) && !defined(ibm032) && !defined(__MACH__) && !defined(MACH)
  16. #include <sys/time.h>
  17. #endif
  18. #include <sys/types.h>
  19. #if (!defined (__STRICT_ANSI__) || defined (__sun__) || defined(sgi) || defined(__osf__)) && !defined(vax)
  20. #if !defined(MACH) &&  !defined(NeXT)
  21. #include <malloc.h>
  22. #endif
  23. #include <stdlib.h>
  24. #endif
  25.  
  26. #if defined (__sun__) && defined (StupidSunHeaders)
  27. #include <sunos.h>
  28. #endif
  29.  
  30. /*
  31.  * We fetch our own strtol-function from crosslib.a, since it
  32.  * differs on so many systems.
  33.  */
  34. extern int strtol_local(char *str, char **ptr, int base);
  35.  
  36. static void convert_bitmap(char *, int);
  37.  
  38. #define NO_MAPPING -4711
  39. #define INVALID         -42
  40.  
  41. #define hexdigit(x) ((x) > 9 ? (x) + 'A' - 10 : (x) + '0')
  42. static char *prog_name, *font_name = "crossfire", *xbm_dir = ".";
  43. static int  font_size = 24, char_defs;
  44. static int  use_bitmaps = 0;
  45. static char *map_file = NULL;
  46.  
  47. static unsigned char mirror[256] = {
  48.         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
  49.         0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 
  50.         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
  51.         0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
  52.         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
  53.         0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
  54.         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
  55.         0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
  56.         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
  57.         0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
  58.         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
  59.         0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
  60.         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
  61.         0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
  62.         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
  63.         0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
  64.         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
  65.         0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
  66.         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
  67.         0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
  68.         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
  69.         0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
  70.         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
  71.         0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
  72.         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 
  73.         0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
  74.         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 
  75.         0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
  76.         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 
  77.         0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
  78.         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 
  79.         0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 
  80. };
  81.  
  82. enum { m_file_char, m_file_list } map_style = m_file_char;
  83.  
  84. static void usage() {
  85.     fprintf(stderr, "Usage: %s [options] [-] [bitmaps]\n", prog_name);
  86.     fprintf(stderr, "Options are:\t-f <mapfile>    maps filename to font position\n");
  87.     fprintf(stderr, "\t\t-b   make bitmap file instead of bdf\n");
  88.     fprintf(stderr, "\t\t-name <fontname>\n\t\t-d <directory>\n\t\t-size <fontsize>\n");
  89.     exit(-1);
  90. }
  91.  
  92. static char *basename(char *n) {
  93.     char *t;
  94.     return (t = strrchr(n, '/')) ? ++t : n;
  95. }
  96.  
  97. static int get_char(FILE *fd) {
  98.     int c;
  99.     if ((c = fgetc(fd)) == EOF) {
  100.     fprintf(stderr, "Fatal: Unexpected eof.\n");
  101.     exit(2);
  102.     }
  103.     return c;
  104. }
  105.  
  106. static int at_end(char *s, char *d) {
  107.     return ! (strcmp(s + strlen(s) - strlen(d), d));
  108. }
  109.  
  110. static int get_byte(FILE *fd) {
  111.     int c;
  112.  
  113.     while (1) {
  114.     c = get_char(fd);
  115.     if (c == '0') {
  116.         if (get_char(fd) != 'x' || fscanf(fd, "%x", &c) == 0) {
  117.         fprintf(stderr, "Fatal: Malformed hex-value.\n");
  118.         exit(4);
  119.         }
  120.         return c;
  121.     }
  122.     }
  123. }
  124.  
  125. static int count_bmaps (char *map_file) {
  126.     FILE *fd;
  127.     char buff[256], path[256];
  128.     int nrofbmaps = 0, ch;
  129.     
  130.     if ((fd = fopen(map_file, "r")) == 0) {
  131.     perror(map_file);
  132.     exit(5);
  133.     }
  134.  
  135.     while (!feof(fd)) {
  136.     fgets(buff, sizeof buff, fd);
  137.     if (sscanf(buff, "\\%d %s", &ch, path) == 2)
  138.         nrofbmaps++;
  139.     }
  140.     fclose (fd);
  141.     return nrofbmaps - 1;
  142. }
  143.  
  144. static void read_mappings(char *map_file) {
  145.     FILE *fd;
  146.     int more = 1, line = 0, ch;
  147.     char path[256];
  148.     char buff[256];
  149.     
  150.     if ((fd = fopen(map_file, "r")) == 0) {
  151.     perror(map_file);
  152.     exit(5);
  153.     }
  154.  
  155.     while (more) {
  156.     line++;
  157.     fgets(buff, sizeof buff, fd);
  158.     if (feof(fd)) {
  159.         more = 0;
  160.     } else {
  161.         if (*buff == '#')
  162.         continue;
  163.  
  164.         if (sscanf(buff, "\\%d %s", &ch, path) != 2) {
  165.         (void) fprintf(stderr, "%s: %d: Syntax error.\n\t%s\n",
  166.                    map_file, line, buff);
  167.         }
  168.         convert_bitmap(path, (int)ch);
  169.     }
  170.     }
  171.     (void) fclose(fd);
  172. }
  173.  
  174.  
  175. static void convert_bitmap(char *file_name, int ch_enc) {
  176.     FILE *fd;
  177.     int w = -1, h = -1, bw, defs, value, x, y;
  178.     char buff[256], func[32], out[24*24], *ch_name;
  179.     char *nextout;
  180.  
  181.     sprintf (buff, "%s/%s", xbm_dir, file_name);
  182.     fd = fopen(buff, "r");
  183.     if (!fd) {
  184.     perror(buff);
  185.     exit(1);
  186.     }
  187.     defs = 1;
  188.     while (defs) {
  189.     (void) fgets(buff, sizeof buff, fd);
  190.     if (feof(fd)) {
  191.         fprintf(stderr, "%s: Fatal: Unexpected end of file\n", file_name);
  192.         exit(2);
  193.     } else if (!strncmp(buff, "static char ", 12) ||
  194.         !strncmp(buff,"static unsigned char ", 21)) {
  195.         /* This is the beginning of the data. */
  196.         defs = 0;
  197.     } else if (sscanf(buff, "#define %s %d", func, &value) == 2) {
  198.         if (at_end(func, "hot")) {
  199.         /* Ignored at this point of development */
  200.         continue;
  201.         } else if (at_end(func, "width")) {
  202.         w = value;
  203.         } else if (at_end(func, "height")) {
  204.         h = value;
  205.         }
  206.     } else {
  207.         fprintf(stderr, "%s: Fatal: Unknown format\n", file_name);
  208.         fprintf(stderr,"Line = `%s`\n", buff);
  209.         exit(2);
  210.     }
  211.     }
  212.  
  213.     if (w%8) {
  214.     fprintf(stderr, "%s: Fatal: Illegal size %dx%d.\nThe width must be a multiple of 8 in this version.\n", file_name, w, h);
  215.     exit(-4);
  216.     }
  217.  
  218.     /*fprintf(stderr, "%s: size %dx%d.\n", file_name, w, h);*/
  219.  
  220.     if (!use_bitmaps) {
  221.     ch_name = basename(file_name);
  222.     
  223.     (void) printf("STARTCHAR %s\nENCODING %d\n",
  224.               ch_name, ch_enc);
  225.     /* Not sure about the following. */
  226.     (void) printf("SWIDTH 1 0\nDWIDTH %d 0\nBBX %d %d 0 0\nBITMAP\n",
  227.               w, w, h);
  228.     bw = (w + 7) / 8;
  229.  
  230.     for (y = 0; y < h; y++) {
  231.         nextout = out;
  232.         for (x = 0; x < bw; x++) {
  233.         char nybble;
  234.         
  235.         value = get_byte(fd);
  236.  
  237.         value = mirror[value];
  238.         nybble = (value & 0xF0) >> 4;
  239.         *nextout++ = hexdigit(nybble);
  240.         nybble = (value & 0x0F);
  241.         *nextout++ = hexdigit(nybble);
  242.         }
  243.         *nextout = '\0';
  244.         printf("%s\n", out);
  245.     }
  246.     printf("ENDCHAR\n");
  247.  
  248.      } else { 
  249.      bw = (w + 7) / 8;
  250.  
  251.      for (y = 0; y < h; y++) {
  252.          for (x = 0; x < bw; x++) {
  253.          value = get_byte(fd);
  254.          putchar (value);
  255.          }
  256.      }
  257.      }
  258.     (void) fclose(fd);
  259. }
  260.  
  261.  
  262. static void epilogue() {
  263.     if (!use_bitmaps)
  264.     printf("ENDFONT\n");
  265. }
  266.  
  267.  
  268. static void prologue() {
  269.     time_t tloc;
  270.  
  271.     if (!use_bitmaps) {
  272.     tloc = time(NULL);
  273.     printf("STARTFONT 2.1\n");
  274.     printf("COMMENT This font was assembled using xbmtobdf on %sFONT %s\n",
  275.            ctime(&tloc), font_name);
  276.     printf("SIZE %d 75 75\nFONTBOUNDINGBOX 0 0 0 0\n", font_size);
  277.     printf("STARTPROPERTIES 2\nFONT_DESCENT 0\nFONT_ASCENT %d\n",
  278.            font_size);
  279.     printf("ENDPROPERTIES\nCHARS %d\n", char_defs);
  280.     }
  281. }
  282.  
  283. static void parse_args(int argc, char **argv) {
  284.     int n, args = 1;
  285.  
  286.     prog_name = argv[0];
  287.     if (argc == 1)
  288.     usage();
  289.  
  290.     for (n = 1; n < argc; n++) {
  291.     if (strcmp(argv[n], "-f") == 0) {
  292.         /*
  293.          * Is the filename missing or is this option given earlier?
  294.          */
  295.         if (n == argc || map_style == m_file_list)
  296.         usage();
  297.         map_style = m_file_list;
  298.         map_file = argv[++n];
  299.         args += 2;
  300.     } else if (strcmp(argv[n], "-size") == 0) {
  301.         if (n == argc)
  302.         usage();
  303.         font_size = (int) atol(argv[++n]);
  304.         args += 2;
  305.     } else if (strcmp(argv[n], "-name") == 0) {
  306.         if (n == argc)
  307.         usage();
  308.         font_name = argv[++n];
  309.         args += 2;
  310.     } else if (strcmp(argv[n], "-d") == 0) {
  311.         if (n == argc)
  312.         usage();
  313.         xbm_dir = argv[++n];
  314.         args += 2;
  315.     } else if (strcmp(argv[n], "-b") == 0) {
  316.         use_bitmaps++;
  317.         args += 1;
  318.     } else if (strcmp(argv[n], "-") == 0) {
  319.         ++args;
  320.         break; /* Don't parse the rest of the arguments */
  321.     } else if ((strcmp(argv[n], "-?") == 0) || 
  322.            (strcmp(argv[n], "-h") == 0)) {
  323.         usage();
  324.     }
  325.     }
  326. }
  327.  
  328.  
  329. int main(int argc, char **argv) {
  330.  
  331.     parse_args(argc, argv);
  332.     char_defs = count_bmaps (map_file);
  333.     prologue();
  334.     read_mappings(map_file);
  335.     epilogue();
  336.  
  337.     return 0;
  338. }
  339.